前面我們談了,coroutine的coroutineScope、繼承、異常處理和取消,也在文中提到了他們和structure concurrency的特性,想必大家都已經有一點基本概念。
這篇文章,主要會先討論為甚麼coroutine要用structure concurrency,是要解決什麼問題,之後複習一下那些提過的特性,幫大家把我的文章前後連貫起來。
在討論為什麼用之前,不如先談談如果不用會怎樣?
假設今天我在需要發出100個請求,(官方blog是舉例1000啦,但我覺得二位數後都很麻煩),我就需要手動追蹤所有的coroutine,檢查Exception,更甚者當我們要取消剩餘任務時,也需要針對全數進行檢查狀態和取消。
如果今天,粗心了忘記取消某個coroutine任務,就會work Leak,那work leak是什麼?
他和memory leak的共通點就是都會占用內存,而work leak更糟糕,他有可能在背後更改到資料庫、發出網路請求,占用cpu資源等等,而coroutine的開發者針對這種問題,引入了Structure concurrency,以達到下列三點
而在kotlin coroutine裡面,分別以下列特性展現
看著熟悉吧,就是前面我講過的那些,既然已經懂了為什麼要用structure concurrency,現在來複習一下吧
在kotlin裡,所有的coroutine都必須在coroutineScope裡面運行,而開啟一個coroutineScope的方式有下面幾種
當我們創建了coroutineScope後,它會自動追蹤在該作用域的每個coroutine,可透過launch/async開啟coroutine,而coroutine的取消是透過 throw CancellationException來取消,取消的行為,只會影響自身跟子coroutine,對parent和sibiling不會有影響
這個特性,不只是Job.cancel()適用,Scope.cancel()也同樣套用這個規則,為了便於管理,我們經常會在一個scope裡面建立多個coroutine執行任務,那當我們不再需要那些任務執行時,只需要對scope呼叫cancel()即可,它會自動取消依附於他之下的coroutine
Structured concurrency guarantees when a scope cancels, all of its coroutines cancel.
Structured concurrency guarantees that when a coroutine errors, its caller or scope is notified.
記得之前講過的Exception如何傳遞的吧,這邊就簡單複習一下,當一個coroutine throw Exception,他會通知她的parent,parent會再通知parent的parent,直到root,再全部取消
如果希望coroutine 出異常時,其他coroutine能繼續執行任務,應當使用supervisorJob或supervisorScope,並妥善處理Exception,具體資訊都寫在這裡了
另一個結構化病發的特點就是追蹤,在coroutineScope或supervisorScope裡面的coroutine,會被自動追蹤
範例是已發出1000個請求,其實不論launch/async,都只會在所有coroutine都完成工作後才會回傳,從而避免了work leak
連結
官方blog